package org.raymond.iworks.study.flowable;

import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.task.api.Task;

import java.util.List;

@Slf4j
public class FinancialReportProcess {
    private static RuntimeService runtimeService;
    private static TaskService taskService;
    private static HistoryService historyService;

    private static FinancialReportProcess instance;

    private FinancialReportProcess(RuntimeService runtimeService, TaskService taskService, HistoryService historyService){
        this.runtimeService = runtimeService;
        this.taskService = taskService;
        this.historyService = historyService;
    }

    public static synchronized FinancialReportProcess instance(RuntimeService runtimeService, TaskService taskService, HistoryService historyService){
        if(instance==null){
            instance = new FinancialReportProcess(runtimeService, taskService, historyService);
        }
        return instance;
    }

    public String startProcess(){
        return runtimeService.startProcessInstanceByKey("financialReport").getId();
    }

    public List<Task> getTasks(){
        return taskService.createTaskQuery().taskDefinitionKey("writeReportTask").list();
    }

    public void getFirstTask(String procId){
        // Get the first task
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();
        for(Task task : tasks){
            log.info("Task for fozzie: {}", task.getName());
            // complete thistoricProcessInstancehe task
            taskService.complete(task.getId());
        }
        log.info("Number of tasks for fozzie: {}", taskService.createTaskQuery().taskAssignee("fozzie").count());

        // Retrieve and claim the second task
        tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
        for (Task task : tasks) {
            log.info("Following task is available for management group: {}", task.getName());
            taskService.claim(task.getId(), "kermit");
        }
        // Completing the second task ends the process
        for (Task task : tasks) {
            taskService.complete(task.getId());
        }

        // verify that the process is actually finished
        HistoricProcessInstance historicProcessInstance =
                historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
        log.info("Process instance end time: {}", historicProcessInstance.getEndTime());
    }
}
